package main

import (
	"fmt"
	"io"
	"os"
	"strings"
	"time"

	"gitee.com/xuender/mysql-proxy/pb"
	"github.com/xuender/oils/base"
	"github.com/xuender/oils/logs"
	"google.golang.org/protobuf/proto"
)

func main() {
	file := base.Panic1(os.Open("logs.pb"))
	defer file.Close()

	data := base.Panic1(io.ReadAll(file))
	log := &pb.Logs{}

	base.Panic(proto.Unmarshal(data, log))

	report := base.Panic1(os.Create("report.md"))
	defer report.Close()

	_, _ = report.WriteString("# SQL报告\n")

	for index, obj := range log.Logs {
		logs.Infow("log", "sql", obj.Sql)

		_, _ = report.WriteString(fmt.Sprintf("\n## No. %d [指纹 %d]\n\n次数: %d\n\n时间: %s\n\n",
			index+1,
			obj.Finger,
			obj.Count,
			time.UnixMilli(obj.TimeStamp).Format("06-01-02 15:04:05")))
		_, _ = report.WriteString(fmt.Sprintf("```sql\n%s\n```\n\n", obj.Sql))

		slice1 := Filter(obj.Rules, func(t *pb.Rule) bool { return !strings.HasPrefix(t.Item, "EXP.") })
		slice2 := Filter(obj.Rules, func(t *pb.Rule) bool { return strings.HasPrefix(t.Item, "EXP.") })

		if len(slice1) > 0 {
			_, _ = report.WriteString("| 代码 | 级别 | 内容 | 规则 | 例子 |\n")
			_, _ = report.WriteString("| - | - | - | - | - |\n")

			for _, rule := range slice1 {
				_, _ = report.WriteString(fmt.Sprintf("| %s | %s | %s | %s | %s |\n",
					rule.Item,
					rule.Severity,
					md(rule.Content),
					md(rule.Summary),
					md(rule.Case),
				))
			}
		}

		if len(slice2) > 0 {
			for _, rule := range slice2 {
				_, _ = report.WriteString(fmt.Sprintf("\n### 代码: %s, 级别: %s\n\n%s%s",
					rule.Item,
					rule.Severity,
					rule.Content,
					rule.Case,
				))
			}
		}
	}
}

func md(str string) string {
	return strings.ReplaceAll(str, "*", "\\*")
}

func Filter[T comparable](elems []T, condition func(T) bool) []T {
	ret := []T{}

	for _, elem := range elems {
		if condition(elem) {
			ret = append(ret, elem)
		}
	}

	return ret
}
